package laba5;

import laba2.*;
import interfaces.task2.FractionNumber;
import interfaces.task2.FractionNumberOperation;
import static java.lang.Math.abs;
import static java.lang.Math.signum;

/**
 *
 * @author yakimovich
 */
public class FractionNumberOperationImpl implements FractionNumberOperation {

    /**
     * adds the specified numbers
     *
     * @return sum the specified numbers
     */
    @Override
    public FractionNumber add(FractionNumber fn, FractionNumber fn1) {
        int dividend = fn.getDividend() * fn1.getDivisor() + fn1.getDividend() * fn.getDivisor();
        int divisor = fn.getDivisor() * fn1.getDivisor();
        return new FractionNumberImpl(dividend, divisor);
    }

//// Бесконечность плюс число
//        if (fn.getDivisor() == 0 && fn1.getDivisor() != 0) {
//            dividend = fn.getDividend();
//            return new FractionNumberImpl(dividend, divisor);
//        }
//// Число плюс бесконечность
//        if (fn.getDivisor() != 0 && fn1.getDivisor() == 0) {
//            dividend = fn1.getDividend();
//            return new FractionNumberImpl(dividend, divisor);
//        }
//
//// Два нуля
//        if (fn.getDividend() == 0 && fn1.getDividend() == 0) {
//            if (fn.getDivisor() != 0 && fn1.getDivisor() != 0) {
//                if (signum(fn.getDivisor()) == signum(fn1.getDivisor())) {
//                    divisor = (int) signum(fn.getDivisor());
//                } else {
//                    divisor = 1;
//                }
//            }
//            return new FractionNumberImpl(dividend, divisor);
//        }
//
//// Две бесконечности
//        if (abs(fn.value()) == Double.POSITIVE_INFINITY && abs(fn1.value()) == Double.POSITIVE_INFINITY) {
//            // Если знаки одинаковые - бесконечность с таким же знаком
//            if (signum(fn.value()) == signum(fn1.value())) {
//                dividend = (int) signum(fn.value());
//                //Если знаки разные - NaN
//            } else {
//                dividend = 0;
//            }
//            return new FractionNumberImpl(dividend, divisor);
//        }
//        //Складываем просто числа
//        if (fn.value() + fn1.value() == 0) {
//            divisor = 1;
//        } else {
//            dividend = fn.getDividend() * fn1.getDivisor() + fn1.getDividend() * fn.getDivisor();
//            divisor = fn.getDivisor() * fn1.getDivisor();
//        }
//        return new FractionNumberImpl(dividend, divisor);
//    }
    /**
     *
     * subtracts the specified numbers
     *
     * @return difference between the specified numbers
     */
    @Override
    public FractionNumber sub(FractionNumber fn, FractionNumber fn1) {
        int dividend = fn.getDividend() * fn1.getDivisor() - fn1.getDividend() * fn.getDivisor();
        int divisor = fn.getDivisor() * fn1.getDivisor();
        return new FractionNumberImpl(dividend, divisor);
    }

//        FractionNumber fnSub = new FractionNumberImpl();
//        if (fn1.getDividend() != 0) {
//            fnSub.setDividend(-fn1.getDividend());
//            fnSub.setDivisor(fn1.getDivisor());
//        } else {
//            fnSub.setDividend(0);
//            fnSub.setDivisor(-fn1.getDivisor());
//        }
//        return add(fn, fnSub);
//    }
    /**
     * multiplies the specified numbers
     *
     * @return the result of multiplying the specified numbers
     */
    @Override
    public FractionNumber mul(FractionNumber fn, FractionNumber fn1) {
        int dividend = fn.getDividend() * fn1.getDividend();
        int divisor = fn.getDivisor() * fn1.getDivisor();
        return new FractionNumberImpl(dividend, divisor);
    }

//        int dividend = 0;
//        int divisor = 0;
//        //Если одно из чисел NaN, результат NaN
//        if (fn.value() == Double.NaN || fn1.value() == Double.NaN) {
//            return new FractionNumberImpl(dividend, divisor);
//        }
//
//        //Если множим бесконечности, результат - бесконечность
//        if (abs(fn.value()) == Double.POSITIVE_INFINITY && abs(fn1.value()) == Double.POSITIVE_INFINITY) {
//            dividend = (int) (signum(fn.value() * signum(fn1.value())));
//            return new FractionNumberImpl(dividend, divisor);
//        }
//
//        //Если первый множитель - бесконечность, а второй - число, то результат бесконечность
//        if (abs(fn.value()) == Double.POSITIVE_INFINITY && abs(fn1.value()) != Double.POSITIVE_INFINITY) {
//            dividend = fn.getDividend() * (int) (signum(fn1.value()));
//            return new FractionNumberImpl(dividend, divisor);
//        }
//
//        //Если первый множитель - число, а второй - бесконечность, то результат бесконечность
//        if (abs(fn.value()) != Double.POSITIVE_INFINITY && abs(fn1.value()) == Double.POSITIVE_INFINITY) {
//            dividend = fn1.getDividend() * (int) (signum(fn.value()));
//            return new FractionNumberImpl(dividend, divisor);
//        }
//
//        //Если первое число нуль, результат нуль
//        if (fn.getDividend() == 0 && fn.getDivisor() != 0 && fn1.getDividend() != 0 && fn1.getDivisor() != 0) {
//            divisor = fn.getDivisor() * (int) (signum(fn1.value()));
//            return new FractionNumberImpl(dividend, divisor);
//        }
//        //Если второе число нуль, результат нуль
//        if (fn.getDividend() != 0 && fn.getDivisor() != 0 && fn1.getDividend() == 0 && fn1.getDivisor() != 0) {
//            divisor = (int) (signum(fn.value())) * fn1.getDivisor();
//            return new FractionNumberImpl(dividend, divisor);
//        }
//
//        dividend = fn.getDividend() * fn1.getDividend();
//        divisor = fn.getDivisor() * fn1.getDivisor();
//
//        return new FractionNumberImpl(dividend, divisor);
//    }
    /**
     *
     * divides the specified numbers
     *
     * @return the result of division the specified numbers
     */
    @Override
    public FractionNumber div(FractionNumber fn, FractionNumber fn1) throws ArithmeticException {

        int dividend = fn.getDividend() * fn1.getDivisor();
        int divisor = fn.getDivisor() * fn1.getDividend();
        try {
            return new FractionNumberImpl(dividend, divisor);
        } catch (IllegalArgumentException e) {
            throw new ArithmeticException("Division by zero!");
        }



    }
//        int dividend = 0;
//        int divisor = 0;
//        //Если делим бесконечности, результат - NaN
//        if (abs(fn.value()) == Double.POSITIVE_INFINITY && abs(fn1.value()) == Double.POSITIVE_INFINITY) {
//            return new FractionNumberImpl(dividend, divisor);
//        }
//        if (abs(fn.value()) == Double.POSITIVE_INFINITY && abs(fn1.value()) == 0) {
//            dividend = fn.getDividend() * fn1.getDivisor();
//            return new FractionNumberImpl(dividend, divisor);
//        }
//
//        FractionNumber fnDiv = new FractionNumberImpl();
//        fnDiv.setDividend(fn1.getDivisor());
//        fnDiv.setDivisor(fn1.getDividend());
//        return mul(fn, fnDiv);
//    }
}
